iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

delete可以幫助我們刪除所有的object。其用法和select非常相近,而事實上delete其實是delete (select ...)的語法糖。

我們繼續使用[Day03]中定義的schema:

type User {
    required name: str;
    multi followers: User;
}

type Article {
    required title: str;
    required author: User;
}

執行下列query生成兩個Article object及四個User object。

insert Article {
   title:= "first article",
   author:= (insert User {name:= "John"})
};

insert Article {
   title:= "second article",
   author:= (insert User {name:= "Jeff"})
};

for name in {"Tom", "Cathy"}
union (insert User {name:= name});

以下我將以Cathy、John、Tom與Jeff來簡單稱呼其name property分別為「"Cathy"」、「"John"」、「"Tom"」與「"Jeff"」的User object。

Delete

假設現在我們想刪除tom,可以這麼寫:

delete User filter .name="Tom";

但delete是一個很重要的操作,通常會先使用select來確認所選到object是否符合:

select User filter .name="Tom";

確認選擇無誤後,再將select換成delete。

如果是面對比較複雜的query時,會建議在with中建立中間變數,像是:

with tom:= (select User filter .name="Tom")
select tom {name};

確認選擇無誤後,再將select換成delete:

with tom:= (select User filter .name="Tom")
delete tom {name};

Bulk delete

如果我們想要刪掉所有的object,您可能會很直覺的想要使用for-loop。但別忘了,delete是delete (select ...)的語法糖,所以回想一下我們是怎麼使用select選擇object的呢?沒錯,直接select就好,所以bulk delete最快的方法是,使用select確認選擇無誤:

select User;
select Article;

再將select換成delete:

delete User;
delete Article;

Deletion police

delete是一個頗為複雜的主題,有可能需要針對每一個object type,制訂不同的deletion police。Easy EdgeDB第十三章中有提到一些可能遇到的複雜情況。

deletion police可以分為target deletion及source deletion兩種。

其中target deletion有:

  • restrict(預設)。
  • delete source。
  • allow。
  • deferred restrict。

而source deletion有:

  • allow。
  • delete target。
  • delete target if orphan。

我們這邊舉幾個常用的情況供大家參考。

on target delete restrict

由於on target delete restrict是預設,所以目前User object的schema與下面的schema其實是相同的:

type User {
    required name: str;
    multi followers: User {
        on target delete restrict;
    };
}

這個deletion police是指當有一個User object連接到其它User object的multi followers link時,這個User object是無法被刪除的。

舉例來說,如果我們將John與Tom指定為Jeff的multi followers link:

with jeff:= (select User filter .name="Jeff"),
     followers:= (select User filter .name in {"John", "Tom"})
update jeff
set {
    followers:= followers
};

假設此時我們試圖delete John:

delete User filter .name="John";

會報錯如下:

edgedb error: ConstraintViolationError: deletion of default::User (988d4658-5248-11ef-af3f-b785e4ec0502) is prohibited by link target policy
Detail: Object is still referenced in link followers of default::User (988d46d0-5248-11ef-af3f-57711cc00e48).

因為John仍在Jeff的multi followers link中。

on target delete delete source

此時如果將delete policy改為on target delete delete source:

type User {
    required name: str;
    multi followers: User {
        on target delete delete source;
    };
}

這個deletion police是指當有一個User object連接到其它User object的multi followers link時,如果這個User object被刪除的話,與其連接的User object也會被刪除。

此時我們可以刪除John:

delete User filter .name="John";

再確認剩下哪些User object:

select User {name, followers};
{
    default::User {
        name: 'Cathy', 
        followers: {}
    }, 
    default::User {
        name: 'Tom', 
        followers: {}
    }
}

可以發現只剩下Cathy及Tom。這是因為當我們刪除John(target)時,也會刪除Jeff(source)。

on source delete delete target

接著我們將delete policy改為on source delete delete target:

type User {
    required name: str;
    multi followers: User {
        on source delete delete target;
    };
}

並重新insert回John跟Jeff:

for name in {"John", Jeff"}
union (insert User {name:= name});

並將John與Tom指定為Jeff的multi followers link:

with jeff:= (select User filter .name="Jeff"),
     followers:= (select User filter .name in {"John", "Tom"})
update jeff
set {
    followers:= followers
};

這個deletion police是指當有一個User object被刪除時,與其multi followers link所連接的User object也會被刪除。

此時我們可以刪除Jeff:

delete User filter .name="Jeff";

再確認剩下哪些User object:

select User {name, followers};
{default::User {name: 'Cathy', followers: {}}}

可以發現只剩下Cathy。這是因為當我們刪除Jeff(source)時,也會刪除John及Tom(target)。


上一篇
[Day05] - 如何update
下一篇
[Day07] - 介紹multi property及array
系列文
一起看無間道學EdgeDB 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言